package com.es.disped.core.shiro;

import java.util.List;
import java.util.Optional;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

import com.es.disped.api.persistence.DelegateService;
import com.es.disped.dao.model.LoginUser;
import com.es.disped.dao.model.RolePermission;


/**
 * @author Anson<br>
 *	Copyright by EasyShare 2019<br>
 *  
 *  All right reserved<br>
 *
 *  Created on 2019年4月7日 下午3:59:57<br>
 *  名称：ShiroRealm<br>
 *
 *  描述：域 realm 实现类<br>
 */
public class ShiroRealm extends AuthorizingRealm {
	
	@Autowired
	DelegateService delegateService;
	
	/**
	 * 为当前登录的Subject授予角色和权限
	 * 
	 * 该方法的调用时机为需授权资源被访问时 每次访问需授权资源时都会执行该方法中的逻辑,如果用户授权内容被缓存，则在不会重复调用该方法
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		Subject subject = SecurityUtils.getSubject();
		LoginUser loginUser=(LoginUser) subject.getPrincipal();
		for(RolePermission rolePermission:loginUser.getUserRoles())
		{
			authorizationInfo.addRole(rolePermission.getRoleCode());
			authorizationInfo.addStringPermission(rolePermission.getRoleCode()+":"+rolePermission.getPermissionCode());
		}
		return authorizationInfo;
	}

	/**
	 * 验证当前登录的Subject 在subject.login(AuthenticationToken)时调用该方法
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		// 获取基于用户名和密码的令牌
		UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
		String phone=usernamePasswordToken.getUsername();
//		usernamePasswordToken.setRememberMe(usernamePasswordToken.isRememberMe());
        LoginUser loginUser = delegateService.selectOne(
        		"com.es.disped.dao.mapper.login.LoginCustomMapper.getLoginUser", phone);
        if (Optional.of(loginUser)
        		.filter(id->loginUser.getUserId()!=null)
        		.isPresent())
        {
    		List<RolePermission> userRoles=delegateService.selectList(
            		"com.es.disped.dao.mapper.login.LoginCustomMapper.getUserRoles", loginUser.getUserId());
    		if(!userRoles.isEmpty())
    		{
    			loginUser.setUserRoles(userRoles);
            	// 交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配
        		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(loginUser,
        				usernamePasswordToken.getPassword(), getName());
        		clearCache(authenticationInfo.getPrincipals());// 认证成功清除之前缓存
        		return authenticationInfo;
    		}
        }
        return null;
	}
	
}
